import time

from activist.Data import Data
from activist.EventInformation import EventInformation
from activist.MetaData import MetaDataFactory, MetaData
from activist.CommandProcessor import CommandProcessor
from activist import errors
from activist.Time import TimeRange

def commandCreate(creator,title,when,description,place):
    rtn = Event(creator,title,when,description,place)
    rtn._test()
    return rtn

class Event(Data):
    def __init__(self,expectedid=None):
        super(Event,self).__init__(expectedid)
        self.command("highlight")
        self.command("category")
        self.command("edit")
        self.command("create")
        self.command("add_group")

    command_create_VERSION = 0
    def command_create(self,creator,
                       title, when, access, description, briefdescription, place, ty, contacts):
        self._createcalled = True
        self._creationdate = time.time()
        if creator:
            MetaDataFactory(self,MetaData.Creator,creator)

                                        # special-case; create() doesn't exist for eventinformation            
        info = EventInformation(self,title,when,access,description,briefdescription,place,ty,contacts,creator=creator)

    command_edit_VERSION = 1
    def command_edit_upgradeFrom(self,version,args,kwargs):
        if version == 0:
            (title,when,description,brief,place,creator) = args
            args = (title,when,[],description,brief,place,creator)
            return (args,kwargs)
        return None
    def command_edit(self,title,when,access,description,brief,place,listingtype,contacts,creator):
        from activist.DataStore import DataStore
        DataStore.clearMonthCache()
                                        # special-case; create() doesn't exist for eventinformation
        return EventInformation(self,title,when,access,description,brief,place,listingtype,contacts,creator)

    command_category_VERSION = 0
    def command_category(self,cat):
        if not cat in self.categories():
            return MetaDataFactory(self,MetaData.BelongsWith,cat)

    command_highlight_VERSION = 0
    def command_highlight(self):
        from activist.DataStore import DataStore
        hl = DataStore.getGenericDataByTitle('highlighted events')
        return MetaDataFactory(self,MetaData.BelongsWith,hl)

    command_add_group_VERSION = 0
    def command_add_group(self, group):
        rtn = MetaDataFactory(self,MetaData.BelongsWith,group)
        return rtn


    ## overriding Data
    def command_delete(self,person):
        for x in self.metadata():
            other = x.fromData()
            if isinstance(other,EventInformation):
                print "forcing delete of INFO:",other,other.metadata()
                other.command_delete(person)

        return Data.command_delete(self,person)
    

    def __str__(self):
        return '<Event@0x%x id:%s>' % (id(self),self.id())

    def isApproved(self):
        return self.info().isApproved()

    def findNextChronological(self):
        from activist.DataStore import DataStore
        l = DataStore.chronologicalEvents()
        idx = -1
        for x in l:
            idx = idx + 1
            if x is self:
                break
        if idx >= 0 and len(l) > idx+1:
            return l[idx+1]
        return None
    def findPreviousChronological(self):
        from activist.DataStore import DataStore
        l = DataStore.chronologicalEvents()
        idx = -1
        for x in l:
            idx = idx + 1
            if x is self:
                break
        if idx > 0:
            return l[idx-1]
        return None
    
    def _test(self):
        print "Event._test \"%s\""%self.info().title()
        print "  ",self.creator()
        print "  ",self._creationdate,time.time()
        print "  meta:"
        for x in self.metadata():
            print "    ",str(x.relationship())+':'+str(x.fromData())
        print "  souces for InformationOf:",self.sourcesForRelationship(MetaData.InformationOf)
        assert len(self.sourcesForRelationship(MetaData.InformationOf))==1

    def getXML(self):
        return """
<event class="activist.Event" id="%(id)s">
  <creation_date>%(creationDate)s</creation_date>
%(meta)s
</event>
        """ % { "creationDate": str(self._creationdate),
                "id":self.id(),
                "meta":self.getMetaXML()
                }
        

    def _postRestore(self):
        pass
#        from activist.DataStore import DataStore
#        self._creator = DataStore[self._creator]
        

    def info(self):
        """
        this could return different versions of the event, based on
        looking further back in the list (i.e. if there are more than
        one associated EventInformation, the newest bit of MetaData
        linking them means the newest version)
        """
        #print "info():",self.sourcesForRelationship(MetaData.InformationOf)
        try:
            return self.sourcesForRelationship(MetaData.InformationOf)[0]
        except IndexError:
            raise errors.Weirdness("No information attached to me!")

    def groups(self):
        from activist.Group import Group
        rtn = []
        print "LOOKING:",self.sourcesForRelationship(MetaData.BelongsWith)
        for x in self.sourcesForRelationship(MetaData.BelongsWith):
            if isinstance(x,Group):
                rtn.append(x)
        return rtn

    def contacts(self):
        rtn = []
        for x in self.groups():
            for y in x.people():
                if not y in rtn:
                    rtn.append(y)
        for x in self.info().contacts():
            if not x in rtn:
                rtn.append(x)
        return rtn
        
    def categories(self):
        from activist.Category import Category
        rtn = []
        for x in self.targetsForRelationship(MetaData.BelongsWith):
            if isinstance(x,Category):
                rtn.append(x)
        print "CATEGORIES for",self.id(),rtn
        return rtn
        
    def metainfo(self):
        """same as above but returns actual metadata object"""
        return self.sourcesForRelationship(MetaData.InformationOf,meta=True)[0]

    def allInfo(self):
        """
        return a list of all the old information. this will be the MetaData
        objects (not just the EventInformation objects) and will not include
        the current info (i.e. it will be empty if there have been no edits).
        """
        return self.sourcesForRelationship(MetaData.InformationOf,meta=True)[1:]



class TimeWrapperForEventInformation:
    """ this inserts the "right" time
    for the event-lists, while preserving the "real"
    (recurring) time for the actual event view
    """
    def __init__(self,info,tm):
        self.time = tm
        self.info = info

    def when(self):
        return self.time.format()
    def whenRaw(self):
        return self.time
    def __getattr__(self,name):
        return getattr(self.info,name)


class ProxyForRecurringEvent(object):

    def __init__(self,event,year,month,day):
        import time
        tm = time.localtime(event.info().whenRaw()._start)
        tm = (year,
              month,
              day,
              tm.tm_hour,
              tm.tm_min,
              tm.tm_sec,
              tm.tm_wday,
              tm.tm_yday,               # fixme
              tm.tm_isdst)
        
        next = event.info().whenRaw().getNextAfter(time.mktime(tm))
        self.thisone = next
        self.time = TimeRange(time.mktime(next),event.info().whenRaw()._duration)
        self._event = event

    def info(self):
        rtn = Event.info(self._event)
        return TimeWrapperForEventInformation(rtn,self.time)
        rtn._when = self.time
        return rtn

    def __getattribute__(self,name):
        if name == "info":
            return object.__getattribute__(self,'info')
        if name in object.__getattribute__(self,'__dict__').keys():
            return object.__getattribute__(self,'__dict__')[name]
        return getattr(object.__getattribute__(self,'_event'),name)


